#include <LNM8F01.h>
#include "display_control.h"
#include "system_init.h"
#include "key_contorl.h"
#include "beep_control.h"

//BIT位
#define BIT0	0x01
#define BIT1	0x02
#define BIT2	0x04
#define BIT3	0x08
#define BIT4	0x10
#define BIT5	0x20
#define BIT6	0x40
#define BIT7	0x80

/**
 * @brief 数码管段码表
 * BIT7~BIT0分别对应A/B/C/D/E/F/G段
 * 1=点亮，0=熄灭
 */
const uint8_t seg_code[12] = {
    0x7E, // 0: 点亮A/B/C/D/E/F段
    0x30, // 1: 点亮B/C段
    0x6D, // 2: 点亮A/B/D/E/G段
    0x79, // 3: 点亮A/B/C/D/G段
    0x33, // 4: 点亮B/C/F/G段
    0x5B, // 5: 点亮A/C/D/F/G段
    0x5F, // 6: 点亮A/C/D/E/F/G段
    0x70, // 7: 点亮A/B/C段
    0x7F, // 8: 点亮所有段
    0x7B, // 9: 点亮A/B/C/D/F/G段
    0x47, // F: 点亮A/E/F/G段
    0x00  // 不显示: 所有段熄灭
};

// 显示状态：空闲/数量/速度/模式/颜色
static display_state_enumType_t displayState = DISPLAY_IDLE;
// 当前显示的4位数值
static uint16_t displayValue = 0;
// 显示刷新计时器
static uint32_t displayTimer = 0;
// 当前扫描行（0~4循环）
static uint8_t scanRow = 0;

// 新增：显示内容模式全局变量和定时器
display_content_mode_enumType_t g_displayContentMode = DISPLAY_MODE_DEFAULT;
uint32_t g_displayContentTimer = 0;

/**
 * @brief 数码管位选引脚定义
 * 第1管：PD4~PD0，用于显示千位和百位
 * 第2管：PC7/6/3/2/1，用于显示十位和个位
 */
static const uint8_t digit_pin[2][5] = {
    {4, 3, 2, 1, 0}, // PD4~PD0
    {7, 6, 3, 2, 1}  // PC7/6/3/2/1
};

/**
 * @brief 将数值分解为4位数字
 * @param value 要显示的数值（0-9999）
 * @param digits 存储分解后的4位数字
 */
static void get_display_digits(uint16_t value, uint8_t digits[4]) {
    digits[0] = (value / 1000) % 10; // 千位
    digits[1] = (value / 100) % 10;  // 百位
    digits[2] = (value / 10) % 10;   // 十位
    digits[3] = value % 10;          // 个位
}

/**
 * @brief 配置所有管脚为输入（不带上下拉）
 */
static void config_pins_as_input(void) {
    PDOE &= ~0x1F;  // 禁用PD4~PD0输出
    PCOE &= ~0xCE;  // 禁用PC7/6/3/2/1输出
    PDPU &= ~0x1F;  // 禁用PD4~PD0上拉
    PCPU &= ~0xCE;  // 禁用PC7/6/3/2/1上拉
    PDPD &= ~0x1F;  // 禁用PD4~PD0下拉
    PCPD &= ~0xCE;  // 禁用PC7/6/3/2/1下拉
}

/**
 * @brief 扫描第1行（PD4拉低）
 * @param seg 段码值
 */
static void scan_row1(uint8_t *seg) {
    // 拉低PD4
		PDOE |= 1 << digit_pin[0][0];
    PDDATA &= ~(1 << digit_pin[0][0]);
    // 根据段码控制其他引脚
    if(seg[1] & BIT5) {PDOE |= 1 << digit_pin[0][1];PDDATA |= (1 << digit_pin[0][1]);} // B3
    if(seg[1] & BIT3) {PDOE |= 1 << digit_pin[0][2];PDDATA |= (1 << digit_pin[0][2]);} // D3
    if(seg[1] & BIT1) {PDOE |= 1 << digit_pin[0][3];PDDATA |= (1 << digit_pin[0][3]);} // F3
    if(seg[1] & BIT0) {PDOE |= 1 << digit_pin[0][4];PDDATA |= (1 << digit_pin[0][4]);} // G3
	
	// 拉低PC7
		PCOE |= 1 << digit_pin[1][0];
    PCDATA &= ~(1 << digit_pin[1][0]);
    // 根据段码控制其他引脚
    if(seg[3] & BIT5) {PCOE |= 1 << digit_pin[1][1];PCDATA |= (1 << digit_pin[1][1]);} // B3
    if(seg[3] & BIT3) {PCOE |= 1 << digit_pin[1][2];PCDATA |= (1 << digit_pin[1][2]);} // D3
    if(seg[3] & BIT1) {PCOE |= 1 << digit_pin[1][3];PCDATA |= (1 << digit_pin[1][3]);} // F3
    if(seg[3] & BIT0) {PCOE |= 1 << digit_pin[1][4];PCDATA |= (1 << digit_pin[1][4]);} // G3
}

/**
 * @brief 扫描第2行（PD3拉低）
 * @param seg1 第1管段码
 * @param seg2 第2管段码
 */
static void scan_row2(uint8_t *seg) {
    // 拉低PD3
		PDOE |= 1 << digit_pin[0][1];
    PDDATA &= ~(1 << digit_pin[0][1]);
    // 根据段码控制其他引脚
    if(seg[1] & BIT6) {PDOE |= 1 << digit_pin[0][0];PDDATA |= (1 << digit_pin[0][0]);} // A3
    if(seg[0] & BIT5) {PDOE |= 1 << digit_pin[0][2];PDDATA |= (1 << digit_pin[0][2]);} // B2
    if(seg[0] & BIT3) {PDOE |= 1 << digit_pin[0][3];PDDATA |= (1 << digit_pin[0][3]);} // D2
    if(seg[0] & BIT2) {PDOE |= 1 << digit_pin[0][4];PDDATA |= (1 << digit_pin[0][4]);} // E2
	
		// 拉低PC6
		PCOE |= 1 << digit_pin[1][1];
    PCDATA &= ~(1 << digit_pin[1][1]);
    // 根据段码控制其他引脚
    if(seg[3] & BIT6) {PCOE |= 1 << digit_pin[1][0];PCDATA |= (1 << digit_pin[1][0]);} // A3
    if(seg[2] & BIT5) {PCOE |= 1 << digit_pin[1][2];PCDATA |= (1 << digit_pin[1][2]);} // B2
    if(seg[2] & BIT3) {PCOE |= 1 << digit_pin[1][3];PCDATA |= (1 << digit_pin[1][3]);} // D2
    if(seg[2] & BIT2) {PCOE |= 1 << digit_pin[1][4];PCDATA |= (1 << digit_pin[1][4]);} // E2
}

/**
 * @brief 扫描第3行（PD2拉低）
 * @param seg1 第1管段码
 * @param seg2 第2管段码
 */
static void scan_row3(uint8_t *seg) {
    // 拉低PD2
		PDOE |= 1 << digit_pin[0][2];
    PDDATA &= ~(1 << digit_pin[0][2]);
    // 根据段码控制其他引脚
    if(seg[1] & BIT4) {PDOE |= 1 << digit_pin[0][0];PDDATA |= (1 << digit_pin[0][0]);} // C3
    if(seg[0] & BIT6) {PDOE |= 1 << digit_pin[0][1];PDDATA |= (1 << digit_pin[0][1]);} // A2
    if(seg[0] & BIT4) {PDOE |= 1 << digit_pin[0][3];PDDATA |= (1 << digit_pin[0][3]);} // C2
    if(seg[0] & BIT1) {PDOE |= 1 << digit_pin[0][4];PDDATA |= (1 << digit_pin[0][4]);} // F2
	
		// 拉低PC3
		PCOE |= 1 << digit_pin[1][2];
    PCDATA &= ~(1 << digit_pin[1][2]);
    // 根据段码控制其他引脚
    if(seg[3] & BIT4) {PCOE |= 1 << digit_pin[1][0];PCDATA |= (1 << digit_pin[1][0]);} // C3
    if(seg[2] & BIT6) {PCOE |= 1 << digit_pin[1][1];PCDATA |= (1 << digit_pin[1][1]);} // A2
    if(seg[2] & BIT4) {PCOE |= 1 << digit_pin[1][3];PCDATA |= (1 << digit_pin[1][3]);} // C2
    if(seg[2] & BIT1) {PCOE |= 1 << digit_pin[1][4];PCDATA |= (1 << digit_pin[1][4]);} // F2
}

/**
 * @brief 扫描第4行（PD1拉低）
 * @param seg1 第1管段码
 * @param seg2 第2管段码
 */
static void scan_row4(uint8_t *seg) {
    // 拉低PD1
		PDOE |= 1 << digit_pin[0][3];
    PDDATA &= ~(1 << digit_pin[0][3]);
    // 根据段码控制其他引脚
    if(seg[1] & BIT2) {PDOE |= 1 << digit_pin[0][0];PDDATA |= (1 << digit_pin[0][0]);} // E3
//    if(seg[1] & BIT5) PDDATA |= (1 << digit_pin[0][1]); // C1
//    if(seg[1] & BIT6) PDDATA |= (1 << digit_pin[0][2]); // B1
    if(seg[0] & BIT0) {PDOE |= 1 << digit_pin[0][4];PDDATA |= (1 << digit_pin[0][4]);} // G2
	
		// 拉低PC2
		PCOE |= 1 << digit_pin[1][3];
    PCDATA &= ~(1 << digit_pin[1][3]);
    // 根据段码控制其他引脚
    if(seg[3] & BIT2) {PCOE |= 1 << digit_pin[1][0];PCDATA |= (1 << digit_pin[1][0]);} // E3
//    if(seg[3] & BIT5) PCDATA |= (1 << digit_pin[1][1]); // C1
//    if(seg[3] & BIT6) PCDATA |= (1 << digit_pin[1][2]); // B1
    if(seg[2] & BIT0) {PCOE |= 1 << digit_pin[1][4];PCDATA |= (1 << digit_pin[1][4]);} // G2
}

/**
 * @brief 扫描第5行（PD0拉低）
 * @param seg1 第1管段码
 * @param seg2 第2管段码
 */
static void scan_row5(uint8_t *seg) {
//    // 拉低PD0
//    PDDATA &= ~(1 << digit_pin[0][4]);
//    // 根据段码控制其他引脚
//    if(seg[x] & BIT1) PDDATA |= (1 << digit_pin[0][2]); // I
//    if(seg[x] & BIT0) PDDATA |= (1 << digit_pin[0][1]); // J
//	
//	// 拉低PD0
//    PCDATA &= ~(1 << digit_pin[1][4]);
//    // 根据段码控制其他引脚
//    if(seg[x] & BIT1) PCDATA |= (1 << digit_pin[1][2]); // I
//    if(seg[x] & BIT0) PCDATA |= (1 << digit_pin[1][1]); // J
}

/**
 * @brief 初始化显示控制模块
 * 配置IO口为推挽输出，初始化显示状态
 */
void init_display(void)
{
    // 初始化IO
    PDOE |= 0x1F;  // 使能PD4~PD0输出
    PDOD &= ~0x1F; // 推挽输出
    PCOE |= 0xCE;  // 使能PC7/6/3/2/1输出
    PCOD &= ~0xCE; // 推挽输出
    
    // 初始化变量
    displayState = DISPLAY_QUANTITY;
    displayValue = 0;
    scanRow = 0;
    displayTimer = get_system_time();
}

/**
 * @brief 设置显示状态
 * @param state 显示状态（空闲/数量/速度/模式/颜色）
 */
void set_display_state(display_state_enumType_t state)
{
    displayState = state;
}

/**
 * @brief 设置显示数值
 * @param value 要显示的数值（0-9999）
 */
void set_display_value(uint16_t value)
{
    displayValue = value;
}

/**
 * @brief 设置显示内容模式接口
 * @param mode 显示内容模式
 */
void set_display_content_mode(display_content_mode_enumType_t mode)
{
    g_displayContentMode = mode;
    g_displayContentTimer = get_system_time();
}

/**
 * @brief 3秒超时自动恢复默认显示
 */
void display_content_mode_timeout_check(void)
{
    if(g_displayContentMode != DISPLAY_MODE_DEFAULT) {
        if(get_system_time() - g_displayContentTimer > 1500) {
            set_display_content_mode(DISPLAY_MODE_DEFAULT);
            play_beep_double();
        }
    }
}

/**
 * @brief 更新显示状态
 * 每2ms扫描一行，5行共10ms完成一个完整扫描周期
 * 第1管显示千位和百位，第2管显示十位和个位
 */
void update_display_state(void)
{
    // 根据模式决定显示内容
    displayState = g_displayContentMode;
    switch(displayState) {
        case DISPLAY_MODE_DEFAULT:
            {
                uint8_t mode = get_key_mode();
                uint8_t color = get_key_color();
                displayValue = mode * 100 + color; // 千百位显示模式，十个位显示颜色
            }
            break;
        case DISPLAY_MODE_QUANTITY: 
            displayValue = get_key_quantity(); 
            break;
        case DISPLAY_MODE_SPEED:
            displayValue = get_key_speed();
            break;
        case DISPLAY_MODE_MODE:
            displayValue = get_key_mode();
            break;
        case DISPLAY_MODE_COLOR:
            displayValue = get_key_color();
            break;
        default:
            displayValue = 0;
            break;
    }
}

// 新增的扫描函数，将被中断调用
void scan_display(void)
{
		static uint16_t lastScanTime = 0;
		uint16_t currentTime = 0;
    uint8_t digits[4];
    uint8_t seg[4];
	
		currentTime = get_system_time();
		// 每4ms扫描一次按键
    if(currentTime - lastScanTime < 2) {
        return;
    }
    lastScanTime = currentTime;

    // 分解数值为数码管的4位
    get_display_digits(displayValue, digits);
    seg[0] = seg_code[digits[0]];
    seg[1] = seg_code[digits[1]];
    seg[2] = seg_code[digits[2]];
    seg[3] = seg_code[digits[3]];

    // 关闭所有输出，防止鬼影
    config_pins_as_input();

    // 根据当前扫描行点亮对应的行列
    switch (scanRow) {
        case 0: scan_row1(seg); break;
        case 1: scan_row2(seg); break;
        case 2: scan_row3(seg); break;
        case 3: scan_row4(seg); break;
        case 4: scan_row5(seg); break;
    }
    
    // 移动到下一行
    scanRow = (scanRow + 1) % 5;
}
